﻿using System;
using System.Linq;
using System.Numerics;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using psieve;
using psieve.factor;
using psieve.sieve;

namespace psieveTest
{
    [TestClass]
    public class TestFactoringSpeed
    {
        private readonly IFactor trialDivision = new TrialDivision(new Eratosthenes());
        private readonly IFactor fermat = new Fermat();

        public static void Test(IFactor fac, BigInteger composite)
        {
            Console.WriteLine("composite: " + composite);

            var factors = fac.Factor(composite).ToList();
            Console.WriteLine("factors: " + String.Join(",", factors));

            Assert.AreEqual(composite, factors.Product());
        }

        public static void Test(IFactor fac, int bits)
        {
            Test(fac, Utils.GenerateProbablyPrimeByBits(bits, 1) * Utils.GenerateProbablyPrimeByBits(bits, 1));
        }

        [TestMethod, Timeout(10000)]
        public void Test_2x10_Fermat()
        {
            Test(fermat, 10);
        }

        [TestMethod, Timeout(10000)]
        public void Test_2x10_TrialDivision()
        {
            Test(trialDivision, 10);
        }

        [TestMethod, Timeout(10000)]
        public void Test_2x20_Fermat()
        {
            Test(fermat, 20);
        }

        [TestMethod, Timeout(10000)]
        public void Test_2x20_TrialDivision()
        {
            Test(trialDivision, 20);
        }

        [TestMethod, Timeout(10000)]
        public void Test_2x25_Fermat()
        {
            Test(fermat, 25);
        }

        [TestMethod, Timeout(10000)]
        public void Test_2x25_TrialDivision()
        {
            Test(trialDivision, 25);
        }

        [TestMethod, Timeout(10000)]
        public void Test_2x30_Fermat()
        {
            Test(fermat, 30);
        }

        [TestMethod, Timeout(10000)]
        public void Test_2x30_TrialDivision()
        {
            Test(trialDivision, 30);
        }

        [TestMethod, Timeout(10000)]
        public void Test_2x35_Fermat()
        {
            Test(fermat, 35);
        }

        [TestMethod, Timeout(10000)]
        public void Test_2x35_TrialDivision()
        {
            Test(trialDivision, 35);
        }
    }
}
